// 名前空間の定義
var koma = {};


///////////////////////////////////////
// 共通関数
///////////////////////////////////////
(function(){
	/**
	 * screenサイズよりデバイスをチェックする。
	 * 480pxより大きければ "pc" を、以下であれば "smp" を返す。
	 */
	koma.deviceCheck = function(){
	   return screen.width > 480 ? 'pc' : 'smp';
	}
})();

///////////////////////////////////////
// koma.Directory: 小説家名鑑（Web-API）にアクセスするクラス
///////////////////////////////////////
(function(){
	/**
	 * constructor
	 */
	koma.Directory = function(){
	}

	/**
	 * Methods definition
	 * 
	 */
	koma.Directory.prototype = {
		index: index_,
		body: body_
	}
	
	/**
	 * ナビゲーション用のインデックスデータGET
	 * 
	 * @param {Function} callback
	 */
	function index_(callback){
		var url = "js/index.json";
		ajax_(url, callback);
	}
	
	/**
	 * 本文データのGET
	 * 
	 * @param {Number} num
	 * @param {Function} callback
	 */
	function body_(num, callback){
		var url = "js/"+num+".json";
		ajax_(url, callback);
	}
	
	/**
	 * Ajax処理を行うメソッド
	 * 
	 * @param {String} url
	 * @param {Function} callback
	 */
	function ajax_(url, callback){
		$.ajax({
			url: url,
			success: function(data){
				if(typeof(data) === "string")
					data = JSON.parse(data);
				
				callback(data);
			},
			error: function(e){
				throw e;
			}
		});
	}
})();


//////////////////////////////////////////////
// koma.Nav: ナビゲーションブロックの処理を行う
//////////////////////////////////////////////
(function(){
	
	/**
	 * constructor
	 */
	koma.Nav = function(){
		this.dir = new koma.Directory();
		this.device = koma.deviceCheck();
	}
	
	/**
	 * Methods definition.
	 *
	 */
    koma.Nav.prototype = {
		show :show_,
		highlight: highlight_
	}

	/**
 	 * ナビゲーションを表示する。
	 * 
	 * @param {Object} tplObj テンプレートオブジェクト
	 *  tplObj = {"pc": <pcテンプレートのセレクタ>, "smp": <スマフォテンプレートのセレクタ>}
	 * @param {String} target 出力先（selector)
	 */
    function show_(tplObj, target) {
		var self = this;
		this.dir.index(function(data){
			$(tplObj[self.device]).tmpl(data).appendTo(target);
			$(window).trigger("navshow");				
		});
	}
	
	/**
	 * 選択リンクをハイライトする
	 * 
	 * @param {String} name 該当のname
	 * @param {String} target ナビゲーションリストのセレクタ名
	 */
	function highlight_(name, target) {
		$(target).each(function(){
			var self = $(this);
			self[self.attr("href") === name ? "addClass" : "removeClass"]("selected");
		})
	}
})();

//////////////////////////////////////////////
// koma.Body: 本文ブロックの処理を行う
//////////////////////////////////////////////
(function(){
	/**
	 * Constructor
	 * 
	 */
	koma.Body = function(){
		this.dir = new koma.Directory();
		this.device = koma.deviceCheck();
	};
	
	/**
	 * Methods definition
	 */
	koma.Body.prototype = {
		show: show_,
		hide: hide_,
		clear: clear_
	}
	
    /**
     * 本文を表示する。
     * 
	 * @param {String} id 表示する小説家ID
	 * @param {String} テンプレートオブジェクトのセレクタ
	 * @param {String} 本文ノードのセレクタ
	 */
	function show_(id, tmpl, target) {
		this.clear(target);

		this.dir.body(id, function(data){
			$(tmpl).tmpl(data).appendTo(target);
			
            $(target).attr("effect", "on"); // スマフォの場合のみ、アニメーションが働く

			$(window).trigger("bodyshow", data); // 処理が終了したことを伝える
		});
	}
	
	/**
	 * 本文を隠す
	 * 
	 * @param {Object} target 本文ノードのセレクタ
	 */
	function hide_(target){
		$(target).attr("effect", "off"); // スマフォの場合のみ、アニメーションが働く
	}
	
	/**
	 * 本文表示を削除する
	 * @param {Object} target
	 */
	function clear_(target){
		$(target).children().remove();
	}
})();

$(function(){
	// インスタンス設定
	koma.nav = new koma.Nav(); // ナビゲーションオブジェクト
	koma.body = new koma.Body(); // 本文オブジェクト
	var device = koma.deviceCheck(); // デバイスをチェックする
	
	/////////////////////////////////////////
	// コントローラ部(イベントリスナー)
	/////////////////////////////////////////
	
	// オブジェクトの処理が終了したとき
	
	$(window).bind("navshow", function(e){
	    // ナビゲーション表示が終わったら、hashchange()を呼び、本文ブロックを表示する
	    $(window).hashchange();
	});
	
	$(window).bind("bodyshow", function(e){
    	// 本文表示が終わった
	});
	
    // URLのハッシュ変更時(ユーザのクリックイベントに対応)
    $(window).hashchange(function(e){
		// ハッシュを取得
        var hash = location.hash || '#';
		
		// ナビゲーションの選択リンクを強調表示
		koma.nav.highlight(hash, "#contents > nav a");

        // ハッシュの値に応じた分岐処理		
		switch(hash){
        case '#':
            // hash指定が無いとき(top画面)
			if(device == "smp"){
				// スマフォの場合は、「戻る」ボタンと本文オブジェクトを隠す（裏にある、ナビゲーションが表示される）
				$("header .back").hide();
				koma.body.hide("#body_");
			} else {
				// PCの場合は、最初の本文が表示される。
                koma.body.show(0, "#bodyTemplate", "#body_");
			}
			break;
		default:
			// hashが指定されたとき(本文指定)
				
	        if (device == "smp") {
				// スマフォの場合は「戻る」ボタンを表示する
				$("header .back").show();
		    }
			// 選択リンクの本文を表示する
	        koma.body.show(hash.replace("#", ""), "#bodyTemplate", "#body_");
		}
    });

	// 処理を開始する
	var start = function(){
    	koma.nav.show({smp:"#navSMPTemplate", pc:"#navPCTemplate"}, "#contents > nav > ul");
	}
	start();
});

// URLバーを隠すためのハック
window.onload = function() {
	setTimeout(scrollTo, 100, 0, 1);
}
